package com.springdoor.wx.api.service.impl;

import com.springdoor.wx.api.entity.WxUser;
import com.springdoor.wx.api.service.LoginService;
import com.springdoor.wx.api.service.WxUserService;
import com.springdoor.wx.config.manager.AsyncManager;
import com.springdoor.wx.config.manager.factory.AsyncFactory;
import com.springdoor.wx.constant.Constants;
import com.springdoor.wx.core.domain.AjaxResult;
import com.springdoor.wx.core.domain.entity.LoginBody;
import com.springdoor.wx.core.domain.entity.LoginUser;
import com.springdoor.wx.core.token.TokenService;
import com.springdoor.wx.utils.string.StringUtils;
import com.springdoor.wx.utils.ip.AddressUtils;
import com.springdoor.wx.utils.ip.IpUtils;
import com.springdoor.wx.utils.login.LoginUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class LoginServiceImpl implements LoginService {

    private static final Logger log = LoggerFactory.getLogger(LoginServiceImpl.class);

    @Autowired
    private TokenService tokenService;

    @Autowired
    private WxUserService userService;

    @Override
    public AjaxResult login(String jsCode) {
        String openid = null;
        String ip = IpUtils.getIpAddr();
        String addreess = AddressUtils.getRealAddressByIP(ip);
        try {
            openid = LoginUtils.tranOpenid(jsCode);
            if (StringUtils.isEmpty(openid)) {
                log.info("获取 openid 失败");
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(jsCode, null, ip, addreess, Constants.LOGIN_FAIL, "获取 openid 失败"));
                return AjaxResult.error("获取 openid 失败");
            }
        } catch (Exception e) {
            log.info("获取 openid 失败 {}", ExceptionUtils.getMessage(e));
            log.error("获取 openid 失败 {}", ExceptionUtils.getMessage(e));
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(jsCode, null, ip, addreess, Constants.LOGIN_FAIL, "获取 openid 失败"));
            return AjaxResult.error("获取 openid 失败");
        }
        return loginByOpenid(openid, ip, addreess, "0");
    }

    @Override
    public AjaxResult loginByOpenid(String openid) {String ip = IpUtils.getIpAddr();
        String addreess = AddressUtils.getRealAddressByIP(ip);
        return loginByOpenid(openid, ip, addreess, "1");
    }

    private AjaxResult loginByOpenid(String openid, String ip, String addreess, String type) {
        LoginUser loginUser = new LoginUser();
        String status = Constants.SUCCESS;
        WxUser user = null;
        String userId = openid;
        try {
            user = userService.findUserByOpenid(openid);
            WxUser wxUser = new WxUser();
            wxUser.setOpenid(openid);
            wxUser.setLoginIp(ip);
            wxUser.setLoginAddress(addreess);
            wxUser.setLoginDate(new Date());
            if (user == null) {
                wxUser.setCreateBy("system");
                wxUser.setUpdateBy("system");
                registerUser(wxUser);
                user = userService.findUserByOpenid(openid);
                status = Constants.REGISTER;
            } else {
                recordLoginInfo(wxUser);
            }

            if (user != null) {
                userId = user.getUserId().toString();
            }

            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userId, user.getUserName(), ip, addreess, status, "登录成功"));
        } catch (Exception e) {
            log.info("获取客户信息异常 --- {}", ExceptionUtils.getMessage(e));
            log.error("获取客户信息异常 --- {}", ExceptionUtils.getMessage(e));
            status = Constants.LOGIN_FAIL;
            String username = null;
            if (user != null && user.getUserId() != null) {
                username = user.getUserName();
            }
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userId, username, ip, addreess, status, e.getMessage()));
            return AjaxResult.error("获取客户信息异常");
        }
        if (user == null) {
            log.info("获取客户信息异常, 未获取到客户信息。");
            return AjaxResult.error("获取客户信息失败");
        }
        try {
            loginUser.setUserId(user.getUserId());
            loginUser.setUserName(user.getUserName());
            loginUser.setIpaddr(ip);
            loginUser.setLoginLocation(addreess);
            loginUser.setUser(user);
            String token = tokenService.createToken(loginUser);
            LoginBody result = new LoginBody();
            result.setOpenid(openid);
            result.setToken(token);
            return AjaxResult.success(result);
        } catch (Exception e) {
            log.info("生成 token 异常 >>> {}", ExceptionUtils.getMessage(e));
            log.error("生成 token 异常 >>> {}", ExceptionUtils.getMessage(e));
        }
        return AjaxResult.error("生成 token 失败");
    }

    private int registerUser(WxUser wxUser) {
        return userService.insertWxUser(wxUser);
    }

    private int recordLoginInfo(WxUser wxUser) {
        return userService.updateWxUser(wxUser);
    }


}
